package com.fast.develop.dm.core.registry;

import cn.hutool.core.util.StrUtil;
import com.fast.develop.dm.core.exception.PluginException;
import com.fast.develop.dm.core.listener.ModuleListener;
import com.fast.develop.dm.core.plugin.Plugin;
import com.fast.develop.dm.core.plugin.PluginRegister;
import com.fast.develop.dm.core.util.TypeUtil;
import org.apache.commons.collections.map.HashedMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 莫寅
 * @createTime 2022-06-09 15:03
 * @desc：
 */
public class ModuleRegistry {

    Map<Plugin, PluginRegister> pluginRegisters = new HashMap<>();
    Map<Class, List<ModuleListener>> moduleListeners = new HashedMap();

    public void register(PluginRegister register){
        Plugin plugin = register.plugin();
        if(pluginRegisters.get(plugin) != null){
            throw new PluginException(StrUtil.format("已存在不能重复注册插件：{}", plugin));
        }

        pluginRegisters.put(plugin, register);
        addModuleListener(register.getListeners());
    }

    public void unRegister(PluginRegister register){
        pluginRegisters.remove(register.plugin());
        removeEvents(register.getListeners());
    }


    private void addModuleListener(List<ModuleListener> moduleListenersList){
        moduleListenersList.forEach(moduleListener -> {
            Class clazz = TypeUtil.getClassesInterfaces(moduleListener.getClass())[0];
            List<ModuleListener> registryModuleListeners = moduleListeners.get(clazz);
            if(registryModuleListeners == null){
                registryModuleListeners = new ArrayList<>();
                moduleListeners.put(clazz, registryModuleListeners);
            }
            registryModuleListeners.add(moduleListener);
        });
    }


    private void removeEvents(List<ModuleListener> moduleListenersList){
        moduleListenersList.forEach(moduleListener -> {
            Class clazz = TypeUtil.getClassesInterfaces(moduleListener.getClass())[0];
            List<ModuleListener> registryModuleListeners = moduleListeners.get(clazz);
            if(registryModuleListeners != null){
                registryModuleListeners.remove(moduleListener);
            }
        });
    }


    public List<ModuleListener> getModuleListeners(Class tClass){
        return moduleListeners.get(tClass);
    }


}
